/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.veditor.model;

import java.awt.Color;
import java.util.Enumeration;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.CSS;
import javax.swing.text.html.StyleSheet;

/**
 *
 * @author Walter Lütgenau
 */
public class HighlightAttributes {
    public static final String ATT_EDIT; // = "style=\"border-width:1px; border-color:black; border-style:inset;\"";
    public static final String ATT_VIEW; // = "style=\"border-width:1px; border-color:black; border-style:outset;\"";
    protected static AttributeSet edit;
    protected static AttributeSet view;

    static {
        edit = createEditAttributeSet();
        view = createViewAttributeSet();
        ATT_EDIT = toStyleAttributeString(edit);
        ATT_VIEW = toStyleAttributeString(view);
    }

    /**
     * Create the attribute set used to mark an editable element.
     * 
     * @return
     */
    protected static AttributeSet createEditAttributeSet() {
        StyleSheet styleSheet = new StyleSheet();
        SimpleAttributeSet result = new SimpleAttributeSet();

        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_WIDTH, "2px");
        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_COLOR, "gray");
        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_STYLE, "inset");

        return result;
    }

    /**
     * Create the attribute set used to mark a view, i.e. an element with
     * an associated view editor.
     * 
     * @return
     */
    protected static AttributeSet createViewAttributeSet() {
        StyleSheet styleSheet = new StyleSheet();
        SimpleAttributeSet result = new SimpleAttributeSet();

        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_WIDTH, "2px");
        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_COLOR, "gray");
        styleSheet.addCSSAttribute(result, CSS.Attribute.BORDER_STYLE, "outset");

        return result;
    }

    /**
     * Create an attribute string from the attribute set.
     * 
     * @param atts
     * @return
     */
    protected static String toStyleAttributeString(AttributeSet atts) {
        StringBuilder buf = new StringBuilder();
        StringBuilder style = new StringBuilder();

        Enumeration i = atts.getAttributeNames();
        while (i.hasMoreElements()) {
            Object key = i.nextElement();
            if (key.equals(StyleConstants.NameAttribute))
                continue;
            Object value = atts.getAttribute(key);

            if (key instanceof CSS.Attribute)
                style.append(" " + key + ":" + value + ";");
            else
                buf.append(" " + key + "=\"" + value + "\"");
        }

        if (style.length() > 0)
            buf.append(" style = \"" + style.toString() + "\"");

        return buf.toString();
    }

    /**
     * Special version of AttributeSet.containsAttributes. Allows to compare two CSS attributes.
     * 
     * @param all
     * @param subset
     * @return
     */
    protected static boolean containsAttributes(AttributeSet all, AttributeSet subset) {
            boolean result = true;

            Enumeration names = subset.getAttributeNames();
            while (result && names.hasMoreElements()) {
                Object name = names.nextElement();

                Object allValue = all.getAttribute(name);
                if (allValue == null)
                    return false;
                
                Object subsetValue = subset.getAttribute(name);

                if (name instanceof CSS.Attribute)
                    result = allValue.toString().equals(subsetValue.toString());
                else
                    result = subsetValue.equals(allValue);
            }

            return result;
        }

    /**
     * Does the attribute set contain all highlight attributes?
     * 
     * @param attributes
     * @return
     */
    public static boolean isHighlight(AttributeSet attributes) {
        return containsAttributes(attributes, edit) || containsAttributes(attributes, view);
    }

}
